package com.zhiyu.service.impl;

import com.zhiyu.entity.VO.ResponseVO;
import com.zhiyu.exception.EncryptException;
import com.zhiyu.service.EncryptService;
import com.zhiyu.service.RedisService;
import com.zhiyu.util.MapBuilder;
import com.zhiyu.util.RSAUtil;
import com.zhiyu.util.ResponseUtil;
import javafx.util.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Map;

@Service
public class EncryptServiceImpl implements EncryptService {

    @Autowired
    private RedisService redisService;

    @Autowired
    private ResponseUtil responseUtil;

    @Value("${spring.redis.key.prefix.encrypt.privateKey}")
    private String privateKeyPrefix;    //私钥在redis中存放的字段前缀

    @Value("${spring.redis.key.expire.encrypt.privateKey}")
    private long privateKeyExpire;    //私钥在redis中的超时时间

    private Pair generateRSAKeyPair() {
        try {
            Pair<String, String> pair = RSAUtil.generateKeyPair();
            return pair;
        } catch (Exception e) {
            throw new EncryptException("生成钥匙对失败");
        }
    }

    @Override
    public ResponseVO getRSAPublicKey(String username) {
        Pair<String, String> keyPair = generateRSAKeyPair();
        String redisField = privateKeyPrefix + username;        //私钥在redis中存放的字段

        redisService.setKey(redisField, keyPair.getValue(), privateKeyExpire);

        Map map = MapBuilder.newInstance().put("publicKey", keyPair.getKey()).build();
        ResponseVO responseVO = responseUtil.success();
        responseVO.setData(map);

        return responseVO;
    }

    @Override
    public boolean verify(String encryptedString, String targetString, String privateKey) {
        if (StringUtils.isEmpty(encryptedString) && StringUtils.isEmpty(targetString))
            return true;

        String decryptedString = RSADecrypt(encryptedString, privateKey);
        if (!decryptedString.equals(targetString))
            return false;

        return true;
    }

    private String RSAEncrypt(String toEncryptString, String publicKey) {
        if (StringUtils.isEmpty(publicKey))
            throw new EncryptException("加密失败");

        try {
            String encryptedString = RSAUtil.encrypt(toEncryptString, publicKey);
            return encryptedString;
        } catch (Exception e) {
            throw new EncryptException("加密失败");
        }
    }

    @Override
    public String RSADecrypt(String toDecryptString, String privateKey) {
        if (StringUtils.isEmpty(privateKey))
            throw new EncryptException("解密失败");

        try {
            String encryptedString = RSAUtil.decrypt(toDecryptString, privateKey);
            return encryptedString;
        } catch (Exception e) {
            throw new EncryptException("解密失败");
        }
    }

    @Override
    public String getPrivateKeyField() {
        return privateKeyPrefix;
    }
}
